package com.libui.dialog

import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.os.Message
import com.libbase.utils.FileUtils
import com.libui.LibUI
import com.libui.R
import com.libui.webview.WebViewEx
import com.tencent.smtt.sdk.WebView

enum class DialogType {
    ALERT,

    CONFIRM;
}

typealias DialogCompletion = (buttonId: String?) -> Unit

class DialogEx private constructor(
    context: Context,
    val id: String,
    private val interactiveHide: Boolean,
    val completion: DialogCompletion?,
    val builder: Builder,
) : Dialog(context, R.style.Theme_DialogEx) {
    companion object {
        val alertButtons = """
            <button id="confirm" class="button-col24" onclick="onButtonClick(this.id)">%s</button>
        """.trimMargin()

        val confirmButtons = """
            <button id="cancel" class="button-col12" onclick="onButtonClick(this.id)">%s</button>
            <button id="confirm" class="button-col12" onclick="onButtonClick(this.id)">%s</button>
        """.trimMargin()

        private val dialogs: MutableMap<String, DialogEx> = mutableMapOf()

        fun closeDialog(dialogId: String, buttonId: String) {
            dialogs[dialogId]?.closeButtonId = buttonId
            dialogs[dialogId]?.dismiss()
        }
    }

    interface Builder {
        fun build(context: Context): DialogEx?
    }

    class DialogBuilder(
        val dialogType: DialogType,
        private val dialogId: String,
        val message: String,
    ) : Builder {
        var title: String? = null

        var confirmButtonText: String? = null

        var cancelButtonText: String? = null

        private var interactiveHide: Boolean = false

        var completion: DialogCompletion? = null

        fun setTitle(text: String?): DialogBuilder {
            this.title = text
            return this
        }

        fun setConfirmButtonText(text: String?): DialogBuilder {
            this.confirmButtonText = text
            return this
        }

        fun setCancelButtonText(text: String?): DialogBuilder {
            this.cancelButtonText = text
            return this
        }

        fun setInteractiveHide(interactiveHide: Boolean): DialogBuilder {
            this.interactiveHide = interactiveHide
            return this
        }

        fun setCompletion(completion: DialogCompletion?): DialogBuilder {
            this.completion = completion
            return this
        }

        override fun build(context: Context): DialogEx? {
            if (dialogs.contains(dialogId)) {
                completion?.let { it(null) }
                return null
            }

            val dialog = DialogEx(context, dialogId, interactiveHide, completion, this)
            dialogs[dialogId] = dialog

            return dialog
        }
    }

    class CustomDialogBuilder(private val dialogId: String) : Builder {
        var url: String? = null
        var resultMsg: Message? = null

        override fun build(context: Context): DialogEx? {
            if (dialogs.contains(dialogId)) {
                return null
            }

            val dialog = DialogEx(context, dialogId, false, null, this)
            dialogs[dialogId] = dialog

            return dialog
        }

        fun setUrl(url: String?): CustomDialogBuilder {
            this.url = url
            return this
        }

        fun setResultMsg(resultMsg: Message): CustomDialogBuilder {
            this.resultMsg = resultMsg
            return this
        }
    }

    var closeButtonId: String? = null

    lateinit var webView: WebViewEx

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.ex_dialog)
        window?.setBackgroundDrawableResource(android.R.color.transparent)
        setCanceledOnTouchOutside(interactiveHide)
        setCancelable(interactiveHide)

        webView = findViewById(R.id.web_view)
        webView.setBackgroundColor(0)
        webView.tag = id

        setOnDismissListener { _ ->
            dialogs.remove(id)
            completion?.let { it(closeButtonId) }
        }

        if (builder is DialogBuilder) {
            set(
                builder.dialogType,
                builder.title, builder.message,
                builder.confirmButtonText, builder.cancelButtonText
            )
        } else if (builder is CustomDialogBuilder) {
            set(builder.url, builder.resultMsg)
        }
    }

    private fun set(
        dialogType: DialogType,
        title: String?,
        message: String,
        confirmButtonText: String? = null,
        cancelButtonText: String? = null
    ) {
        val htmlPath = LibUI.instance.dataSource?.htmlPath ?: return

        var htmlStr = FileUtils.instance
            .readAssetFile("${htmlPath}/dialog.html", context) ?: return

        htmlStr = htmlStr.replace("{{ dialogId }}", id)

        htmlStr = htmlStr.replace("{{ title }}", title ?: "")

        htmlStr = htmlStr.replace("{{ message }}", message)

        val buttonsHtml = when (dialogType) {
            DialogType.ALERT -> {
                alertButtons.format(confirmButtonText ?: "确定")
            }
            DialogType.CONFIRM -> {
                confirmButtons.format(cancelButtonText ?: "取消", confirmButtonText)
            }
        }

        htmlStr = htmlStr.replace("{{ buttons }}", buttonsHtml)

        webView.loadDataWithBaseURL(
            "file:///android_asset/${htmlPath}/",
            htmlStr,
            "text/html",
            "utf-8",
            null
        )
    }

    private fun set(url: String?, resultMsg: Message?) {
        if (resultMsg != null) {
            val transport: WebView.WebViewTransport = resultMsg.obj as WebView.WebViewTransport
            transport.webView = this.webView
            resultMsg.sendToTarget()
        }

        if (url != null) {
            webView.loadUrl(url)
        }
    }
}